Skip to content

feat(ci): add cross-platform final build checks#279

Open
konard wants to merge 5 commits into
ProverCoderAI:mainfrom
konard:issue-278-d92a50df7e27
Open

feat(ci): add cross-platform final build checks#279
konard wants to merge 5 commits into
ProverCoderAI:mainfrom
konard:issue-278-d92a50df7e27

Conversation

@konard
Copy link
Copy Markdown
Contributor

@konard konard commented May 12, 2026

Summary

  • Adds a Final Build GitHub Actions workflow for Ubuntu, macOS, and Windows that builds both packages, smoke-tests both CLIs, and uploads package tarballs.
  • Makes setup/package scripts cross-platform by removing shell-only script wrappers and replacing raw chmod with a Bun helper.
  • Bounds clone-cache mirror refreshes to branch and tag refs so CI does not fetch hosted forge PR refs during cache reuse.

Reproduction and Verification

  • Reproduced the package-script portability gap with packages/app/tests/docker-git/package-scripts-cross-platform.test.ts before implementing the script changes.
  • Reproduced the clone-cache CI failure mode from run 25728183189: E2E (Clone cache) timed out after 1800s on the second cache reuse case while refreshing broad refs/*.
  • Added a regression test in packages/lib/tests/core/templates.test.ts proving mirror refreshes include refs/heads/* and refs/tags/* but not broad refs/*.

Local Checks

  • bun run --cwd packages/lib test -- tests/core/templates.test.ts
  • bun run --cwd packages/app test -- tests/docker-git/package-scripts-cross-platform.test.ts
  • bun run build
  • bun run typecheck
  • bun run lint
  • bun run lint:effect
  • bun run check:dist-deps-prune
  • bun run test
  • git diff --check

Mathematical Guarantees

Invariants

  • forall os in {linux, macos, windows}: final-build(os) -> build(os) and cli_help(app, os) and cli_help(session_sync, os)
  • forall r in clone_cache_refresh_refs: r in refs/heads/* union refs/tags/*
  • forall npm_script in checked_scripts: not contains(npm_script, "bash -lc")

Preconditions

  • Bun and Node versions are provided by the shared setup action.
  • Generated dist artifacts exist before package smoke checks.

Postconditions

  • Package tarballs are produced on each matrix OS.
  • Clone-cache refresh no longer requests refs/pull/* or refs/merge-requests/* through broad refs/*.

Complexity

  • Clone-cache refresh changes from O(|all remote refs|) to O(|heads| + |tags|).

SOURCE: n/a

Fixes #278

konard added 2 commits May 12, 2026 09:48
Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#278
@konard konard changed the title [WIP] Надо сделать что бы запускалось как на виндоус так и на линукс удобно. feat(ci): add cross-platform final build checks May 12, 2026
@konard konard marked this pull request as ready for review May 12, 2026 10:20
@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

Working session summary

Done. Updated existing PR 279 and marked it ready:

#279

Implemented:

  • Added cross-platform Final Build workflow for Ubuntu, macOS, and Windows.
  • Removed Unix-only script assumptions from package scripts.
  • Added executable marking helper with Windows no-op behavior.
  • Fixed clone-cache mirror refresh to fetch only heads/tags instead of all refs.
  • Added regression tests for cross-platform scripts and clone-cache refspec invariants.

Verified locally:
build, typecheck, lint, lint:effect, check:dist-deps-prune, full test, targeted regression tests, and git diff --check.

Verified CI on latest SHA a872a79230edcea7405200a732154568f2051d81:
Check, Final Build, Snapshot, and Checking Dependencies all passed. Working tree is clean.

SOURCE: n/a.


This summary was automatically extracted from the AI working session output.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Model: GPT-5.5
  • Provider: OpenAI
  • Public pricing estimate: $31.863471

📊 Context and tokens usage:

  • 672.7K / 1.1M (64%) input tokens, 61.0K / 128K (48%) output tokens

Total: (672.7K + 22.4M cached) input tokens, 61.0K output tokens, $31.863471 cost

🤖 Models used:

  • Tool: OpenAI Codex
  • Requested: gpt-5.5
  • Model: GPT-5.5 (gpt-5.5)

📎 Log file uploaded as Repository (83153KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@skulidropek
Copy link
Copy Markdown
Member

в Final build надо ещё проверить что запускается browser
И через менюшку у него работает клонирование проектов

@skulidropek
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Добавлен Final Build CI для кроссплатформенной проверки сборки и smoke-проверок на Linux, macOS и Windows.
  • Bug Fixes

    • Ограничено обновление зеркального кэша клонирования до веток и тегов, чтобы избежать лишних рефов.
  • Chores

    • Обновлены скрипты запуска/сборки для кроссплатформенной совместимости.
    • Добавлен универсальный утилитный скрипт для пометки сборок как исполняемых на POSIX‑системах.
  • Tests

    • Добавлены кроссплатформенные и интеграционные тесты для сценариев запуска и создания проектов.

Walkthrough

Этот PR добавляет кросс-платформенную поддержку: скрипт для пометки исполняемых файлов, замену bash-обёрток в npm-скриптах на прямой вызов Bun, ограничение refspec для зеркального refresh git до веток и тегов и новый CI workflow Final Build с проверками и упаковкой артефактов для Linux/macOS/Windows.

Changes

Cross-platform build and CI pipeline

Layer / File(s) Summary
Cross-platform executable marking infrastructure
scripts/mark-executable.mjs, packages/docker-git-session-sync/package.json, packages/app/tests/docker-git/package-scripts-cross-platform.test.ts, packages/app/package.json
Добавлен Bun/Node-скрипт для установки битов исполнения на POSIX, session-sync-скрипт сборки теперь вызывает этот helper, добавлены property-based тесты (fast-check) проверяющие отсутствие bash и raw chmod в пользовательских скриптах; fast-check добавлен в devDependencies.
CLI script simplification across packages
package.json, packages/app/package.json
Корневые и app npm-скрипты убирают bash -lc и "$@" — теперь собирают CLI и вызывают собранный entrypoint через bun напрямую для команд clone, open, docker-git, list, start.
Clone-cache mirror refspec restrictions
packages/lib/src/core/templates-entrypoint/tasks.ts, packages/app/src/lib/core/templates-entrypoint/tasks.ts, packages/lib/tests/core/templates.test.ts
Добавлены cloneCacheRefreshRefspecs и заменён широкий +refs/*:refs/* на ограниченные refs/heads/* и refs/tags/*; тесты убеждаются, что генерируемый entrypoint использует только эти рефспеки и не содержит PR/MR-шаблонов.
Cross-platform CI/CD final-build workflow
.github/workflows/final-build.yml, .github/actions/setup/action.yml, .changeset/cross-platform-final-build.md, scripts/final-build/browser-web-smoke.mjs, packages/app/tests/*
Новый workflow Final Build запускается по dispatch и PR в main на ubuntu/macOS/windows, использует зафиксированные Bun 1.3.11 и Node 24.14.0, компилит рабочую область, выполняет CLI и браузерные smoke-проверки (включая browser-web-smoke.mjs и набор Vitest-тестов), упаковывает пакеты в .tgz без выполнения package scripts и загружает артефакты; установка OpenSSH в setup-экшене теперь выполняется только на Linux.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Across all the systems, from Windows to Linux so fair,
Our scripts now run portable, without any bash in the air!
Mark-executable marks files with cross-platform grace,
While CI builds validate from every OS place. 🚀


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Requirements Alignment ❌ Error Требуемые property-based тесты (fc.property) для инвариантов действий создания проекта и quick-create не реализованы, как требовали review comments. Добавить fc.property тесты в actions-project-create.test.ts и app-ready-create.test.ts для проверки инвариантов создания и быстрого клонирования.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding cross-platform final build checks as part of CI improvements.
Description check ✅ Passed The description includes detailed summary, reproduction steps, local checks, and verification information, though it lacks explicit mention of the fixed issue link at the top level of the template structure.
Linked Issues check ✅ Passed All key requirements from issue #278 are met: cross-platform CI workflow for Linux/macOS/Windows, final build verification, script portability fixes, and regression tests validate the implementation.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: CI workflow setup, script cross-platform refactoring, clone-cache refspec fixes, and corresponding tests. No extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Regression ✅ Passed No security regressions. Workflow uses read-only permissions, avoids pull_request_target, scripts validate input, proper path resolution, no exposed credentials, pinned dependencies.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/final-build.yml:
- Around line 27-33: The workflow .github/workflows/final-build.yml currently
only checks CLIs ("Verify docker-git CLI starts" and "Verify session sync CLI
starts"); add a new step after those that performs the requested browser/UI
clone smoke check by launching a headless browser and exercising the UI clone
path (open app served from the build, navigate to the clone UI/menu, trigger a
clone, and assert success). Name the step clearly (e.g., "Verify browser UI
clone smoke check") and implement it using your existing test runner or a
lightweight headless tool (Playwright/puppeteer or an npm script) so it starts
the built web app, runs the UI clone flow, and fails the job on error.

In `@packages/app/tests/docker-git/package-scripts-cross-platform.test.ts`:
- Around line 24-34: Add fast-check property-based assertions covering the same
invariants currently tested by the table-driven checks: the "no bash" invariant
for each launch script and the "no chmod" invariant for the package build
script. Use fast-check's fc.assert with an fc.property that generates indices or
script entries from the existing launchScripts array and validates that the
selected entry.script does not match /\bbash(?:\.exe)?\b/u (referencing
launchScripts and entry.scriptName/entry.packageName for contextual failure
messages), and another property that checks sessionSyncPackage.scripts.build
does not match /\bchmod\s+/u. Replace or augment the existing for-loop and
single expect with these fc.assert(fc.property(...)) calls so the test file
package-scripts-cross-platform.test.ts uses property-based testing for the
invariants.

In `@packages/lib/tests/core/templates.test.ts`:
- Around line 77-86: The test for "renderEntrypoint clone cache" is missing
negative assertions for pull-request and merge-request refspecs; update the spec
for the entrypoint returned by renderEntrypoint(makeTemplateConfig()) to assert
it does not contain the undesired refs by adding checks that entrypoint does not
contain "'+refs/pull/*:refs/pull/*'" and
"'+refs/merge-requests/*:refs/merge-requests/*'". Ensure you add these two
expect(...).not.toContain(...) assertions alongside the existing negative check
so the test prevents regressions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f798fdcc-08da-4eff-8545-a01201bd5aac

📥 Commits

Reviewing files that changed from the base of the PR and between 65c4f84 and a872a79.

📒 Files selected for processing (11)
  • .changeset/cross-platform-final-build.md
  • .github/actions/setup/action.yml
  • .github/workflows/final-build.yml
  • package.json
  • packages/app/package.json
  • packages/app/src/lib/core/templates-entrypoint/tasks.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
  • packages/docker-git-session-sync/package.json
  • packages/lib/src/core/templates-entrypoint/tasks.ts
  • packages/lib/tests/core/templates.test.ts
  • scripts/mark-executable.mjs

Comment thread .github/workflows/final-build.yml
Comment thread packages/lib/tests/core/templates.test.ts
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 13, 2026

AI Session Backup

Commit: 7cf5e22
Status: success
Files: 3 (10.69 MB)
Links: README | Manifest

git status

On branch issue-278-d92a50df7e27
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/tests/docker-git/actions-project-create.test.ts`:
- Around line 94-137: Add property-based tests using fast-check to validate
invariants for the browser create project flow: create new tests that use
fc.assert(fc.property(...)) to vary projectId (fc.uuid()) and cursor
(fc.integer) and inside each property reset mocks
(eventStreamCloseMock.mockReset(), startCreateProjectMock.mockImplementation(()
=> Effect.succeed({ accepted: true, cursor, projectId }))), invoke the flow via
makeBrowserActionContext(), submitCreateInputs(...), and trigger the event
handler via readCreateEventHandler(); assert invariants: eventStreamCloseMock
called exactly once, the projectId returned by startCreateProjectMock equals the
id in the project.created event you trigger, and reloadDashboard (from context)
is called once after creation; place these tests alongside the existing
it.effect test and use the same helpers (submitCreateInputs,
readCreateEventHandler, startCreateProjectMock, eventStreamCloseMock,
reloadDashboard) so they run within the Effect test harness.

In `@packages/app/tests/docker-git/app-ready-create.test.ts`:
- Around line 98-120: Add a property-based test using fast-check that for any
valid repository URL with quickCreate:true the submitCreateInputs path and
invariants hold: use fc.property to generate valid repo URLs (and optional
branch segments), call submitCreateBuffer(..., { quickCreate: true }), then
assert submitCreateInputsMock was called once with a payload matching
CreateInputs (including repoUrl and repoRef) and that the repoUrl → outDir
invariant holds (compute expected outDir from the generated repo URL and compare
to the outDir in the mocked call); keep existing assertions around
requireCreateViewValue and createInitialFlowView and locate the test scaffolding
via submitCreateBuffer, submitCreateInputsMock, submitCreateInputs,
requireCreateViewValue, and createInitialFlowView.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 740fe432-8b4e-42b9-9fb6-0dba1356aba9

📥 Commits

Reviewing files that changed from the base of the PR and between a872a79 and 7cf5e22.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • .github/workflows/final-build.yml
  • package.json
  • packages/app/package.json
  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
  • packages/docker-git-session-sync/package.json
  • packages/lib/tests/core/templates.test.ts
  • scripts/final-build/browser-web-smoke.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (6)
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • scripts/final-build/browser-web-smoke.mjs
  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/docker-git-session-sync/package.json
  • packages/app/package.json
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
  • package.json
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/actions-project-create.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/app-ready-create.test.ts
  • packages/app/tests/docker-git/package-scripts-cross-platform.test.ts
package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Dependencies must include Effect-TS (effect: ^3.x) for monadic effects and @effect/schema: ^0.x for validation with strong typing.

Dependencies like effect (^3.x) and @effect/schema (^0.x) are mandatory; project must enforce monadic composition through Effect.

Files:

  • package.json
🔇 Additional comments (6)
packages/lib/tests/core/templates.test.ts (1)

84-95: LGTM!

packages/docker-git-session-sync/package.json (1)

13-13: LGTM!

packages/app/package.json (1)

31-36: LGTM!

Also applies to: 117-117

package.json (1)

26-28: LGTM!

Also applies to: 39-39, 50-50

packages/app/tests/docker-git/package-scripts-cross-platform.test.ts (1)

25-37: LGTM!

.github/workflows/final-build.yml (1)

1-51: LGTM!

Comment on lines +94 to +137
describe("browser create project action", () => {
beforeEach(() => {
eventStreamCloseMock.mockReset()
loadProjectDetailsMock.mockReset()
openProjectEventStreamMock.mockReset()
startCreateProjectMock.mockReset()
startCreateProjectMock.mockImplementation(() =>
Effect.succeed({
accepted: true,
cursor: 7,
projectId: project.id
})
)
openProjectEventStreamMock.mockImplementation(() => ({ close: eventStreamCloseMock }))
})

it.effect("clones a project through the browser menu create flow", () =>
Effect.gen(function*(_) {
const { context, output, reloadDashboard, setMessage } = makeBrowserActionContext()

submitCreateInputs(createInputs, context)

yield* _(waitForAssertion(() => {
expect(openProjectEventStreamMock).toHaveBeenCalledTimes(1)
}))
readCreateEventHandler()(projectCreatedEvent)

yield* _(waitForAssertion(() => {
expect(context.setSelectedProject).toHaveBeenCalledWith(project)
}))

expect(startCreateProjectMock).toHaveBeenCalledWith(expectedCreateDraft)
expect(openProjectEventStreamMock).toHaveBeenCalledWith(project.id, expect.objectContaining({ initialCursor: 7 }))
expect(eventStreamCloseMock).toHaveBeenCalledTimes(1)
expect(loadProjectDetailsMock).not.toHaveBeenCalled()
expect(reloadDashboard).toHaveBeenCalledTimes(1)
expect(context.setSelectedProjectId).toHaveBeenCalledWith(project.id)
expect(context.setSelectedMenuIndex).toHaveBeenCalledWith(1)
expect(setMessage).toHaveBeenLastCalledWith("Created octocat/Hello-World.")
expect(output()).toContain("[create] Project creation requested")
expect(output()).toContain("[create] Project accepted: project-1")
expect(output()).toContain("[create] Project created")
}))
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Рассмотрите добавление property-based тестов для инвариантов создания проекта.

Текущий тест правильно использует Effect-TS паттерны, но не проверяет инварианты через fast-check. Инварианты, подходящие для property-based тестирования:

  • Любое успешное создание проекта должно закрывать event stream ровно один раз
  • projectId из ответа и из события project.created всегда совпадают
  • Dashboard reload всегда вызывается после успешного создания

Рекомендация: добавить fc.property тесты для этих инвариантов.

🧪 Пример property-based теста
it.effect("event stream always closes exactly once for any valid project creation", () =>
  Effect.gen(function*(_) {
    fc.assert(fc.property(
      fc.uuid(),
      fc.integer({ min: 1, max: 100 }),
      (projectId, cursor) => {
        eventStreamCloseMock.mockReset()
        startCreateProjectMock.mockImplementation(() =>
          Effect.succeed({ accepted: true, cursor, projectId })
        )
        
        submitCreateInputs(createInputs, context)
        readCreateEventHandler()(/* trigger created event */)
        
        expect(eventStreamCloseMock).toHaveBeenCalledTimes(1)
      }
    ))
  }))

Согласно руководству по кодированию "**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/actions-project-create.test.ts` around lines 94
- 137, Add property-based tests using fast-check to validate invariants for the
browser create project flow: create new tests that use
fc.assert(fc.property(...)) to vary projectId (fc.uuid()) and cursor
(fc.integer) and inside each property reset mocks
(eventStreamCloseMock.mockReset(), startCreateProjectMock.mockImplementation(()
=> Effect.succeed({ accepted: true, cursor, projectId }))), invoke the flow via
makeBrowserActionContext(), submitCreateInputs(...), and trigger the event
handler via readCreateEventHandler(); assert invariants: eventStreamCloseMock
called exactly once, the projectId returned by startCreateProjectMock equals the
id in the project.created event you trigger, and reloadDashboard (from context)
is called once after creation; place these tests alongside the existing
it.effect test and use the same helpers (submitCreateInputs,
readCreateEventHandler, startCreateProjectMock, eventStreamCloseMock,
reloadDashboard) so they run within the Effect test harness.

Comment on lines +98 to +120
it("submits a quick create clone from the Create menu", () => {
const { setCreateViewSpy } = submitCreateBuffer(
"https://github.com/octocat/Hello-World/tree/feature-x",
{ quickCreate: true }
)

expect(submitCreateInputsMock).toHaveBeenCalledTimes(1)
expect(submitCreateInputsMock.mock.calls[0]?.[0]).toEqual(
{
cpuLimit: "",
enableMcpPlaywright: false,
force: false,
forceEnv: false,
gpu: "none",
outDir: "/home/dev/.docker-git/octocat/hello-world",
ramLimit: "",
repoRef: "feature-x",
repoUrl: "https://github.com/octocat/Hello-World/tree/feature-x",
runUp: true
} satisfies CreateInputs
)
expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0])).toEqual(createInitialFlowView())
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Отсутствуют property-based тесты для инвариантов quick-create.

Согласно руководству по кодированию, тестовые файлы .test.ts должны использовать fast-check для проверки математических свойств и инвариантов. Текущий тест проверяет только один конкретный сценарий.

Рекомендация: добавить fc.property тесты, проверяющие, что для любого валидного URL репозитория с quickCreate: true функция submitCreateInputs вызывается с корректным CreateInputs payload и инвариант repoUrloutDir сохраняется.

🧪 Пример property-based теста
+import * as fc from "fast-check"
+
+  it("quick create always produces valid CreateInputs for any repo URL", () => {
+    fc.assert(fc.property(
+      fc.webUrl({ withFragments: false, withQueryParameters: false }),
+      (repoUrl) => {
+        submitCreateInputsMock.mockReset()
+        const { setCreateViewSpy } = submitCreateBuffer(repoUrl, { quickCreate: true })
+        
+        expect(submitCreateInputsMock).toHaveBeenCalledTimes(1)
+        const inputs = submitCreateInputsMock.mock.calls[0]?.[0]
+        expect(inputs?.repoUrl).toBeTruthy()
+        expect(inputs?.outDir).toBeTruthy()
+      }
+    ))
+  })

Согласно руководству по кодированию "**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/app-ready-create.test.ts` around lines 98 -
120, Add a property-based test using fast-check that for any valid repository
URL with quickCreate:true the submitCreateInputs path and invariants hold: use
fc.property to generate valid repo URLs (and optional branch segments), call
submitCreateBuffer(..., { quickCreate: true }), then assert
submitCreateInputsMock was called once with a payload matching CreateInputs
(including repoUrl and repoRef) and that the repoUrl → outDir invariant holds
(compute expected outDir from the generated repo URL and compare to the outDir
in the mocked call); keep existing assertions around requireCreateViewValue and
createInitialFlowView and locate the test scaffolding via submitCreateBuffer,
submitCreateInputsMock, submitCreateInputs, requireCreateViewValue, and
createInitialFlowView.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Надо сделать что бы запускалось как на виндоус так и на линукс удобно.

2 participants